package com.ruoyi.framework.sms.impl;

import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.EnvironmentUtil;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.config.properties.SmsAliyunProperties;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.sms.SmsClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;


/**
 * 阿里云短信服务
 */
@Slf4j
@Service
@EnableConfigurationProperties(SmsAliyunProperties.class)
public class SmsClientAliyunImpl implements SmsClient {

    @Autowired
    SmsAliyunProperties smsAliyunProperties;

    @Autowired
    Client client;


    @Autowired
    private RedisCache redisCache;

    @Override
    public void sendCode(String phone) {
        String code = String.format("%06d", UUID.getRandom().nextInt(0, 999999));
        log.info("phone:{},code:{}", phone, code);
        sendCode(phone, code);
    }

    @Override
    public void sendCode(String phone, String code) {
        if(!smsAliyunProperties.getEnable()){
            return;
        }
        HashMap<String, String> map = new HashMap<>();
        map.put("code", code);
        String jsonStr = JSONObject.toJSONString(map);
        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                .setSignName(smsAliyunProperties.getSignName())
                .setTemplateCode(smsAliyunProperties.getTemplateCode())
                .setPhoneNumbers(phone)
                .setTemplateParam(jsonStr);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            if (!EnvironmentUtil.isDev()){
                SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
            }
            String verifyKey = CacheConstants.SMS_CODE_KEY + ":" + phone;
            redisCache.setCacheObject(verifyKey, code, 5, TimeUnit.MINUTES);
        } catch (TeaException error) {
            error.printStackTrace();
            // 如有需要，请打印 error
            log.error("1短信发送失败：手机号：{},参数：{},错误信息：{}",phone,code,error.getMessage());
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            log.error("2短信发送失败：手机号：{},参数：{},错误信息：{}",phone,code,error.getMessage());
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
        log.info("短信发送成功：手机号：{},参数：{}",phone,code);
    }

    @Override
    public boolean verifyCode(String phone, String code) {
        if(!smsAliyunProperties.getEnable()){
            return true;
        }
        String verifyKey = CacheConstants.SMS_CODE_KEY + ":" + phone;
        String captcha = redisCache.getCacheObject(verifyKey);
        if (captcha == null)
        {
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha))
        {
            throw new CaptchaException();
        }
        redisCache.deleteObject(verifyKey);
        return true;
    }
}
